import ExcelFormulaContext from '@/ts/scripting/excel/formula';
import { parseCellRefs } from '@/ts/scripting/js/CellRefParserPlugin';
import { parseColumnRefs } from '@/ts/scripting/js/ColumnRefParserPlugin';
import { coordToCell1Base } from '../../util/report';
import { XSheet } from '@/ts/base/schema';
import FormServiceBase from '../../services/FormServiceBase';

export interface SheetRef {
  cells: string[];
  ranges: {
    from: string,
    to: string,
  }[];
  columns?: {
    column: string;
    floatRow: string;
  }[]
}

export interface ReportRefInfo {
  currentRefs: SheetRef;
  otherSheetRefs: Dictionary<SheetRef>;
}

export interface ColumnRefInfo {
  columns: string[];
}



export default class RefParser {

  /**
   * 解析公式中的单元格引用
   * @param expression 公式
   * @returns 单元格引用信息
   */
  public static cellRefs(expression: string): ReportRefInfo {
    return parseCellRefs(expression);
  }

  public static columnRefs(expression: string): ColumnRefInfo {
    return parseColumnRefs(expression);
  }

  public static cellRefsV2(expression: string, sheet: XSheet, service: FormServiceBase) {
    const ret: ReportRefInfo = {
      currentRefs: {
        cells: [],
        ranges: [],
        columns: [],
      },
      otherSheetRefs: {},
    };

    const {
      refs,
      formula,
    } = service.reportCtx.parseRefs(
      expression,
      {
        col: 1,
        row: 1,
        sheet: sheet.code,
      },
      sheet,
    );
    for (const ref of refs) {
      ref.sheet ||= sheet.code;

      let sheetRef = ret.currentRefs;
      if (ref.sheet != sheet.code) {
        if (!ret.otherSheetRefs[ref.sheet]) {
          ret.otherSheetRefs[ref.sheet] = {
            cells: [],
            ranges: [],
            columns: [],
          };
        }
        sheetRef = ret.otherSheetRefs[ref.sheet];
      }

      if ('from' in ref) {
        sheetRef.ranges.push({
          from: coordToCell1Base(ref.from),
          to: coordToCell1Base(ref.to),
        });
      } else if ('column' in ref) {
        sheetRef.columns!.push({
          column: ref.column,
          floatRow: ref.floatRow,
        });
      } else {
        sheetRef.cells.push(coordToCell1Base(ref));
      }
    }


    return {
      formula,
      refs: ret
    };
  }

}
